package com.suixun.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.concurrent.ListenableFuture;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import com.suixun.Constants;
import com.suixun.controller.vo.SendMessForm;
import com.suixun.dao.sendmessagemanage.SendMessageManageDAO;
import com.suixun.entity.School;
import com.suixun.entity.SendMessageInfo;
import com.suixun.entity.form.ParamForm;
import com.suixun.entity.form.SendMessageForm;
import com.suixun.entity.page.PageModel;
import com.suixun.queue.SMSDeal;
import com.suixun.queue.SendMessageDeal;
import com.suixun.service.SchoolService;
import com.suixun.service.SendMessageService;
import com.suixun.service.credits.SendGoodsService;
import com.suixun.util.Constant;
import com.suixun.util.DateUtil;
import com.suixun.vo.SendMessageVO;

import cn.jiguang.common.ClientConfig;
import cn.jpush.api.JPushClient;

/**
 * 
 * <p>
 * Title: SendMessageServiceImpl
 * </p>
 * <p>
 * 功能描述:处理消息推送业务逻辑
 * </p>
 * 
 * @author 陈显强
 * @date 2016年12月22日上午9:20:37
 * @version 1.0
 */
@Service("sendMessageService")
public class SendMessageServiceImpl implements SendMessageService {
	protected static Logger logger = LoggerFactory.getLogger(SendMessageServiceImpl.class);
	@Autowired
	private SendMessageManageDAO sendMessageManageDAO;

	@Autowired
	private SendGoodsService sendGoodsService;

	@Autowired
	private SchoolService schoolService;

	@Autowired
	private SendMessageDeal sendMessageDeal;
	
	@Autowired
	private SMSDeal sMSDeal;

	private final JPushClient jpushClient = new JPushClient(Constant.JpushConstant.MASTER_SECRET,
			Constant.JpushConstant.APP_KEY, null, ClientConfig.getInstance());

	/**
	 * <p>
	 * Title: querySendMessageList
	 * </p>
	 * <p>
	 * 功能描述:分页查询推送消息
	 * </p>
	 * 
	 * @param param
	 * @return
	 */
	@Override
	public PageModel<SendMessageVO> querySendMessageList(SendMessageForm sendMessage) {
		PageModel<SendMessageVO> pageModel = new PageModel<SendMessageVO>();
		String operationername = null;
		if (sendMessage != null) {
			if (StringUtils.isNotEmpty(sendMessage.getPagecount())) {
				pageModel.setPagesize(Integer.parseInt(sendMessage.getPagecount()));
			}
			if (StringUtils.isNotEmpty(sendMessage.getOperationername())) {
				operationername = new StringBuffer().append("%").append(sendMessage.getOperationername()).append("%")
						.toString();
			}
		}
		pageModel.getQueryparam().put("operationername", operationername);
		Integer totleRows = sendMessageManageDAO.countRows(pageModel);
		pageModel.setTotlepage(totleRows);
		if (sendMessage != null) {
			if (StringUtils.isNotEmpty(sendMessage.getPagenumber())) {
				pageModel.setCurrentpage(Integer.parseInt(sendMessage.getPagenumber()));
			}
		}
		List<SendMessageInfo> sendMessages = sendMessageManageDAO.queryByPaging(pageModel);
		List<SendMessageVO> sendMessageVOs = new LinkedList<>();
		for (SendMessageInfo sendMessageInfo : sendMessages) {
			SendMessageVO sendMessageVO = new SendMessageVO();
			sendMessageVOs.add(toSendMessageVO(sendMessageVO, sendMessageInfo));
			sendMessageVO = null;
		}
		pageModel.setQueryresult(sendMessageVOs);
		return pageModel;
	}

	/**
	 * <p>
	 * Title: addSendMessage
	 * </p>
	 * <p>
	 * 功能描述:添加推送消息
	 * </p>
	 * 
	 * @param sendMessage
	 * @return
	 */
	@Override
	@Transactional
	public int addSendMessage(SendMessageForm sendMessage) {
		if (!StringUtils.isNotEmpty(sendMessage.getSendtype()) || !StringUtils.isNotEmpty(sendMessage.getReceivetype())
				|| !StringUtils.isNotEmpty(sendMessage.getSendrate()) || !StringUtils.isNotEmpty(sendMessage.getTitle())
				|| !StringUtils.isNotEmpty(sendMessage.getContent()) || sendMessage.getStarttime() == null) {
			return -1;
		}
		SendMessageInfo sendMessageInfo = new SendMessageInfo();
		// 消息推送时间不能在晚上23点-早上8点之间
		sendMessageInfo.setSendtime(DateUtil.formatStringToTime(sendMessage.getStarttime(), "yyyy-MM-dd HH:mm:ss"));
		Calendar sendtime = Calendar.getInstance();
		sendtime.setTime(sendMessageInfo.getSendtime());
		if (sendtime.get(Calendar.HOUR_OF_DAY) <= 7 || sendtime.get(Calendar.HOUR_OF_DAY) >= 23) {
			return -2;
		}
		// 推送时间必须大于当前时间
		try {
			int compare = DateUtil.compareTotime3(sendMessageInfo.getSendtime(), new Date());
			if (compare != 2) {
				return -2;
			}
		} catch (ParseException e) {
			SendMessageServiceImpl.logger.error("sendMessageError:the time is error", e);
		}
		// 消息类型
		sendMessageInfo.setSendtype(Integer.valueOf(sendMessage.getSendtype()));
		// 接收消息对象
		sendMessageInfo.setReceivetype(sendMessage.getReceivetype());
		switch (sendMessage.getReceivetype()) {
		case "1":
			break;
		case "2":
			if (!StringUtils.isNotEmpty(sendMessage.getPeopletels())) {
				return -1;
			}
			sendMessageInfo.setPeopletels(sendMessage.getPeopletels());
			break;
		}
		// 发送频率
		switch (sendMessage.getSendrate()) {
		case "1":
			sendMessageInfo.setSendrate(1);
			sendMessageInfo.setSendcount(1);
			break;
		case "2":
			sendMessageInfo.setSendrate(2);
			sendMessageInfo.setSendcount(3);
			break;
		case "3":
			sendMessageInfo.setSendrate(3);
			sendMessageInfo.setSendcount(7);
			break;
		default:
			return (-3);
		}
		sendMessageInfo.setTitle(sendMessage.getTitle());
		sendMessageInfo.setEndtime(DateUtil.formatStringToTime(sendMessage.getEndtime(), "yyyy-MM-dd HH:mm:ss"));
		sendMessageInfo.setContent(sendMessage.getContent());
		sendMessageInfo.setOperationername(sendMessage.getOperationername());

		return sendMessageManageDAO.addSendMessage(sendMessageInfo);
	}

	/**
	 * <p>
	 * Title: querySendMessage
	 * </p>
	 * <p>
	 * 功能描述:通过id查询推送消息
	 * </p>
	 * 
	 * @param sendMessage
	 * @return
	 */
	@Override
	public SendMessageVO querySendMessage(SendMessageForm sendMessage) {
		Integer messageid = Integer.parseInt(sendMessage.getMessageid());
		SendMessageInfo sendMessageInfo = sendMessageManageDAO.querySendMessageById(messageid);
		if (sendMessageInfo == null) {
			return null;
		}
		return toSendMessageVO(new SendMessageVO(), sendMessageInfo);
	}

	/**
	 * <p>
	 * Title: toSendMessageVO
	 * </p>
	 * <p>
	 * 功能描述:将SendMessageInfo转换为SendMessageVO方便页面展示
	 * </p>
	 * 
	 * @param sendMessageVO
	 * @param sendMessageInfo
	 * @return
	 */
	public SendMessageVO toSendMessageVO(SendMessageVO sendMessageVO, SendMessageInfo sendMessageInfo) {
		String receiveType = null;
		switch (sendMessageInfo.getReceivetype()) {
		case "1":
			receiveType = "全部";
			break;
		case "2":
			receiveType = "教师端";
			break;
		case "3":
			receiveType = "家长端";
			break;
		}
		sendMessageVO.setReceivetype(receiveType);
		switch (sendMessageInfo.getSendtype()) {
		case 1:
			sendMessageVO.setSendtype("短信");
			break;
		case 2:
			sendMessageVO.setSendtype("推送");
			break;
		}
		sendMessageVO.setTitle(sendMessageInfo.getTitle() == null ? null : sendMessageInfo.getTitle());
		sendMessageVO.setStarttime(sendMessageInfo.getSendtime() == null ? null
				: DateUtil.formatDateToString(sendMessageInfo.getSendtime(), null));
		sendMessageVO.setEndtime(sendMessageInfo.getEndtime() == null ? null
				: DateUtil.formatDateToString(sendMessageInfo.getEndtime(), null));
		String sendrate = null;
		switch (sendMessageInfo.getSendrate()) {
		case 1:
			sendrate = "只发一次";
			break;
		case 2:
			sendrate = "连续三天";
			break;
		case 3:
			sendrate = "连续一周";
			break;
		}
		sendMessageVO.setSendrate(sendrate);
		sendMessageVO.setRegions(sendMessageInfo.getRecevieOrgType());
		sendMessageVO.setOperationername(
				sendMessageInfo.getOperationername() == null ? null : sendMessageInfo.getOperationername());
		sendMessageVO.setMessageid(sendMessageInfo.getMessageid().toString());
		sendMessageVO.setContent(sendMessageInfo.getContent() == null ? null : sendMessageInfo.getContent());
		sendMessageVO.setMdtids(sendMessageInfo.getMdtids());
		sendMessageVO.setPeopletels(sendMessageInfo.getPeopletels());
		switch (sendMessageInfo.getStatus()) {
		case 1:
			sendMessageVO.setStatus("有效");
			break;
		case 0:
			sendMessageVO.setStatus("无效");
			break;
		}
		sendMessageVO.setSendcount(sendMessageInfo.getSendcount().toString());
		return sendMessageVO;
	}

	/**
	 * <p>
	 * Title: deleteSendMessage
	 * </p>
	 * <p>
	 * 功能描述:删除指定推送消息
	 * </p>
	 * 
	 * @param sendMessage
	 * @return
	 */
	@Override
	public int deleteSendMessage(SendMessageForm sendMessage) {
		return sendMessageManageDAO.deleteSendMessage(Integer.parseInt(sendMessage.getMessageid()));
	}

	@Override
	@Async("suixunExecutor")
	public ListenableFuture<Integer> sendMessage(SendMessForm form) {
		if (null == form) {
			return new AsyncResult<Integer>(-1);
		}
		SendMessageInfo sendMessageInfo = new SendMessageInfo();

		if (StringUtils.isBlank(form.getStarttime())) {
			form.setStarttime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
		}
		// 消息推送时间不能在晚上23点-早上8点之间
		sendMessageInfo.setSendtime(DateUtil.formatStringToTime(form.getStarttime(), "yyyy-MM-dd HH:mm:ss"));
		Calendar sendtime = Calendar.getInstance();
		sendtime.setTime(sendMessageInfo.getSendtime());
		if (sendtime.get(Calendar.HOUR_OF_DAY) <= 7 || sendtime.get(Calendar.HOUR_OF_DAY) >= 23) {
			return new AsyncResult<Integer>(-2);
		}

		Gson gson = new Gson();

		if (!CollectionUtils.isEmpty(form.getRegions())) {
			sendMessageInfo.setRecevieOrgType(gson.toJson(form.getRegions()));
		}

		// 消息类型
		sendMessageInfo.setSendtype(Integer.valueOf(form.getSendtype()));
		// 接收消息对象 类型(老师，学生)
		sendMessageInfo.setReceivetype(form.getReceivetype());

		if (!StringUtils.isBlank(form.getPeopletels())) {
			sendMessageInfo.setPeopletels(form.getPeopletels());
		}

		// 发送频率
		switch (form.getSendrate()) {
		case "1": // 只发一次
			sendMessageInfo.setSendrate(1);
			sendMessageInfo.setSendcount(1);
			break;
		case "2": // 三天一次
			sendMessageInfo.setSendrate(2);
			sendMessageInfo.setSendcount(3);
			break;
		case "3": // 一周一次
			sendMessageInfo.setSendrate(3);
			sendMessageInfo.setSendcount(7);
			break;
		default:
			break;
		}
		sendMessageInfo.setTitle(form.getTitle());
		sendMessageInfo.setEndtime(DateUtil.formatStringToTime(form.getEndtime(), "yyyy-MM-dd HH:mm:ss"));
		sendMessageInfo.setContent(form.getContent());
		sendMessageInfo.setOperationername(form.getOperationername());

		sendMessageManageDAO.sendMessage(sendMessageInfo);

		// --------------------发送逻辑
		List<String> tels = Lists.newArrayList();

		if (StringUtils.isNotBlank(form.getPeopletels())) // 只发送部分手机号
		{
			tels = Arrays.asList(form.getPeopletels().split("[,，]"));
		} else // 根据范围来获取接收者信息
		{
			Set<String> schoolnames = Sets.newHashSet();

			form.getRegions().parallelStream().forEach(region -> {

				ParamForm param = new ParamForm();

				if (CollectionUtils.isEmpty(region.getSchoolNames())) {
					if (StringUtils.isNotBlank(region.getTown()))// 选择了区县
					{
						param.setTown(region.getTown());

					}
					if (StringUtils.isNotBlank(region.getCity()))// 选择了市
					{
						param.setCity(region.getCity());
					}
					param.setProvince(region.getProvince()); // 选择了省

					List<School> schools = schoolService.querySchoollist(param);

					if (!CollectionUtils.isEmpty(schools)) {
						schoolnames.addAll(
								schools.parallelStream().map(School::getSchoolname).collect(Collectors.toList()));
					}
				} else {
					schoolnames.addAll(region.getSchoolNames());
				}

			});

			int range = 0; // 用户对象 0所有 1教师 2家长

			if (form.getReceivetype().equals("1")) // 所有
			{
				range = 0;
			} else if (form.getReceivetype().equals("2")) // 老师
			{
				range = 1;
			} else // 家长
			{
				range = 2;
			}

			Set<String> tes = sendGoodsService.getPeopletels(schoolnames, range);

			tels.addAll(tes);
		}

		if (!form.getSendtype().equals("1")) // 推送
		{
			if (StringUtils.isBlank(form.getPeopletels()) && CollectionUtils.isEmpty(form.getRegions())) // 推送给所有人
			{
				sendMessageDeal.JiGuangPushAll(form.getTitle(), form.getContent(), true, false, null, jpushClient, "");
			} else // 推送部分
			{
				if (CollectionUtils.isEmpty(tels)) {
					return new AsyncResult<Integer>(0);
				}

				// --------极光推送(免费版) 1分钟只能推送600个设备, 一次只能推送 1000个
				List<String> telephoneList = Lists.newArrayList();
				for (int i = 0; i < tels.size(); i = i + 500) {
					if (i + 500 >= tels.size()) {
						telephoneList = tels.subList(i, tels.size());
					} else {
						telephoneList = tels.subList(i, i + 500);
					}
					if ("DEV".equals(Constants.get_platform_env())) {
						sendMessageDeal.JiGuangPush(telephoneList, form.getTitle(), form.getContent(), false, false,
								null, jpushClient, "");
					} else {
						sendMessageDeal.JiGuangPush(telephoneList, form.getTitle(), form.getContent(), true, false,
								null, jpushClient, "");
					}
				}

			}
		} else if (!form.getSendtype().equals("2")) // 短信
		{
			for (String telephone : tels) {
				 //将短信内容放到队列里去
				 Map<String,String> arr = Maps.newHashMap();
				 arr.put("module", "sendMessage");
				 arr.put("title", form.getTitle());
				 arr.put("telephone", telephone);
				 arr.put("content", form.getContent());
				 sMSDeal.send(arr);
			 }
		}

		return new AsyncResult<Integer>(1);
	}

}
